#include <Ape/MT/Mutex.h>

#include <Ape/Exception.h>

namespace Ape {
	namespace MT {
		Mutex::Mutex (const String mutexName)
				: Name (mutexName), m_Locked(false)
		{
			pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
			m_Handle = m;
		}
		Mutex::~Mutex() {
			Unlock();
		}
		
		void Mutex::Lock() {
			if (pthread_mutex_lock (&m_Handle) ) {
				throw Exception (L"Failed to lock mutex");
			}
			m_Locked = true;
		}
		void Mutex::Unlock() {
			if (!m_Locked)
				return;
			if (pthread_mutex_unlock (&m_Handle) ) {
				throw Exception (L"Failed to unlock mutex");
			}
			m_Locked = false;
		}
		
		
		MutexLock::MutexLock (Mutex& m)
				: m_Locked (true),
				M (m)
		{
			M.Lock();
		}
		MutexLock::~MutexLock() {
			ForceUnlock();
		}
		
		void MutexLock::ForceUnlock() {
			if (m_Locked) {
				M.Unlock();
				m_Locked = false;
			}
		}
	}
}
